package edu.ucla.cs.typecast.util.slf;

import java.io.*;
import java.util.*;
import java.util.regex.*;

public class ScriptLogReader {
	protected boolean eof = false;

	protected boolean strict;

	protected BufferedReader br;

	public ScriptLogReader(File f, boolean strict) throws FileNotFoundException {
		this(new FileReader(f), strict);
	}

	public ScriptLogReader(String s, boolean strict) {
		this(new StringReader(s), strict);
	}

	public ScriptLogReader(Reader r, boolean strict) {
		this.br = new BufferedReader(r);
		this.strict = strict;
	}
	
	/**
	 * Check if an additional entry can be read.
	 * 
	 * @return
	 */

	public boolean hasNextEntry() {
		return !eof;
	}
	
	/**
	 * Read an entry.
	 * 
	 * @return
	 * @throws IOException
	 */

	public Map<String, String> readEntry() throws IOException {
		// If reeach EOF, no more entry can be read

		if (eof)
			return null;

		// By default, the entry is empty

		Map<String, String> entry = new HashMap<String, String>();

		// Process each line until the end of entry

		int lineNum = 0;
		while (true) {
			// Read a line
			// Stop on EOF
			// Increase line #
			// Trim the line read

			String line = br.readLine();
			if (line == null) {
				eof = true;
				break;
			}

			lineNum++;
			String trimmedLine = line.trim();

			// A line that has only has a "%" sign indicates end of entry

			if (trimmedLine.equals("%"))
				break;

			// Empty lines are ignored

			if (trimmedLine.length() == 0) {
				continue;
			}

			// If the line starts with a "#":
			// ... that's a comment; ignore the line

			if (trimmedLine.startsWith("#"))
				continue;

			// Find a pattern "<key> = <value>"; extract key and value
			
			Matcher matcher = Pattern.compile("^(.*?)\\s*=\\s*(.*?)$",
					Pattern.CASE_INSENSITIVE).matcher(line.trim());
			if (matcher.matches()) {
				entry.put(matcher.group(1), matcher.group(2));
			}

			// If no such pattern found in current line...

			else {
				if (strict) {
					// Complain about the parse error

					throw new ScriptLogParseException(trimmedLine, lineNum);
				} else {
					// Ignore the parse error
				}
			}
		}

		return entry;
	}
}
